/*******************************************************************************
 * Copyright (c) 2008 Sylvain Sicard.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License v2.1
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     Sylvain Sicard - initial API and implementation
 ******************************************************************************/
/*
 * Created on 24 oct. 2005
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package fr.jade.console.cmd;

import java.lang.reflect.Method;
import java.lang.reflect.Type;

import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.api.Interface;
import org.objectweb.fractal.api.NoSuchInterfaceException;
import org.objectweb.fractal.api.type.InterfaceType;
import org.objectweb.fractal.util.Fractal;

import fr.jade.console.core.AbstractCommand;
import fr.jade.console.core.Command;
import fr.jade.console.core.Environment;

/**
 * @author Sylvain Sicard
 */
public class Desc extends AbstractCommand implements Command{

  public String getDescription(){
    return "describe an interface";
  }
  
  public String getHelp(){
    return "desc \n"+
           "\t-fc <itfName> describes Fractal interface\n"+
           "\t-lg <itfName> describes language interface\n";
  }
  
  public String getName() {
    return "desc";
  }
  
	/**
	 * @param args args[0] : desc
	 *             args[1] : itfName
	 */ 
	public Object execute(String[] args, Environment env) throws Throwable {
		String itfName = null;
		String opt = null;
		if(args.length != 3){
		  System.out.println(getHelp());
		}else{
		  opt = args[1];
			itfName = args[2];
		}
		
		Component curent = (Component)env.getEnvVar("current");
    String curentName = Fractal.getNameController(curent).getFcName();
    
    try{
      Interface itf = (Interface)curent.getFcInterface(itfName); 
      InterfaceType itfType = (InterfaceType)itf.getFcItfType();
      if(opt.equals("-fc")){
        System.out.println(curentName + "." + itfName);
    		System.out.println("GUID: "+itf.getFcItfGUId());
    		System.out.println("Is internal: "+itf.isFcInternalItf());
    		System.out.println("Signature: "+itfType.getFcItfSignature());
    		System.out.println("Is client: "+itfType.isFcClientItf());
    		System.out.println("Is collection: "+itfType.isFcCollectionItf());
    		System.out.println("Is optional: "+itfType.isFcOptionalItf());
  		}else if(opt.equals("-lg")){
  		  ClassLoader cl = getClass().getClassLoader();
  		  Class<?> c = cl.loadClass(itfType.getFcItfSignature());
  		  System.out.println(curentName + "." + itfName);
  		  for(Method m : c.getMethods()){
  		    StringBuffer sb = new StringBuffer();
          sb.append(m.getName());
          sb.append("(");
          boolean first = true;
          for (Class<?> t : m.getParameterTypes()) {
            if(first){
              sb.append(t.getName());
              first = false;
            }else{
              sb.append(",").append(t.getClass().getName());
            }
          }
          sb.append(")");
  		    System.out.println("|--"+sb.toString());
  		  }
  		}else{
  		  System.out.println(getHelp());
  		}
		}catch(NoSuchInterfaceException e){
      System.out.println(itfName+" no such interface in component "+curentName);
    }
		return null;
	}
	

}
